package ru.aslanov.schedule.server.services;

import ru.aslanov.schedule.model.DataItem;
import ru.aslanov.schedule.model.Group;
import ru.aslanov.schedule.model.Operation;
import ru.aslanov.schedule.model.ScheduleItem;
import ru.aslanov.schedule.server.AccessDeniedException;
import ru.aslanov.schedule.server.AccessManager;
import ru.aslanov.schedule.server.gcalendar.GCalendarSyncService;

import javax.jdo.PersistenceManager;
import javax.jdo.annotations.PersistenceAware;
import javax.servlet.http.HttpServletRequest;

/**
 * Created by IntelliJ IDEA.
 * Created: Feb 3, 2010 1:37:32 PM
 *
 * @author Sergey Aslanov
 */
@PersistenceAware
public class ScheduleItemService extends ParentChildService<ScheduleItem, Group> {

    public ScheduleItemService() {
        super("group", "group", null);
    }

    @Override
    protected Class<Group> getParentClass() {
        return Group.class;
    }

    @Override
    protected String getDefaultInputLang(HttpServletRequest request) {
        return getParent(getPersistanceManager(), request).getSchedule().getDefaultInputLanguage();
    }

    @Override
    protected void checkParentViewAccess(String parentKey, HttpServletRequest request) throws AccessDeniedException {
        AccessManager am = AccessManager.getInstance();
        if (!am.hasAccessToGroup(parentKey, Operation.VIEW)) {
            throw new AccessDeniedException(request);
        }
    }


    @Override
    protected Group getParent(PersistenceManager pm, HttpServletRequest request) {
        final ScheduleItem existingObject = findExistingObject(request, getPersistanceManager());
        if (existingObject != null) {
            return existingObject.getGroup();
        } else {
            return super.getParent(pm, request);
        }
    }

    @Override
    protected void makeObjectPersistent(PersistenceManager pm, ScheduleItem object, HttpServletRequest request) {
        getParent(pm, request).getScheduleItems().add(object);
    }

    @Override
    protected void fillDataItem(DataItem dataItem, ScheduleItem object, HttpServletRequest request, PersistenceManager pm) throws Exception {
        super.fillDataItem(dataItem, object, request, pm);
        setAttr(dataItem, "dayOfWeek", object.getDayOfWeek());
        setAttr(dataItem, "startTime", object.getStartTime());
        setAttr(dataItem, "endTime", object.getEndTime());
        setAttr(dataItem, "locationKey", object.getLocationKey());
        //setAttr(dataItem, "locationName", object.getLocation() != null ? object.getLocation().getName() : null);
        setAttr(dataItem, "googleEventId", object.getGoogleEventId());
        setAttr(dataItem, "group", object.getGroup());
    }


    

    @Override
    protected Class<ScheduleItem> getEntityClass() {
        return ScheduleItem.class;
    }

    @Override
    protected boolean checkPermission(ScheduleItem existingEntity, HttpServletRequest request, PersistenceManager pm, Operation operation) throws AccessDeniedException {
        String groupKey = existingEntity != null ? existingEntity.getGroup().getEncodedKey() : getParentKey(request);
        return AccessManager.getInstance().hasAccessToGroup(groupKey, operation);
    }

    @Override
    protected void onChange(PersistenceManager pm, ScheduleItem object, Operation operation, HttpServletRequest request) {
        final Group group = object.getGroup();
        group.syncDays(operation == Operation.REMOVE ? object.getEncodedKey() : null);

        final GCalendarSyncService syncService = new GCalendarSyncService();
        if (operation == Operation.CREATE || operation == Operation.UPDATE) {
            syncService.updateScheduleItem(pm, object, group);
        } else if (operation == Operation.REMOVE) {
            syncService.removeScheduleItem(pm, object, group);
        }
        final String scheduleKey = group.getSchedule().getEncodedKey();
        executeAfterCommit(new Runnable() {
            @Override
            public void run() {
                syncService.sendEvents(scheduleKey);
            }
        });                
    }
}
